package com.demo.blockchain.controller;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.demo.blockchain.BlockChain;
import com.demo.blockchain.ProofWork;
import com.demo.blockchain.domain.Block;
import com.demo.blockchain.domain.TransactionRecord;

@RestController
public class Controller {

	@Autowired
    private ServletContext servletContext;

	/**注册节点
	 * @return
	 * @throws MalformedURLException
	 */
	@PostMapping("/register")
	public Set<String> register(@RequestBody String addresses) throws MalformedURLException{
		BlockChain blockChain = BlockChain.getInstance();
		return blockChain.registerNode(addresses);
	}

	/**解决冲突
	 * @return
	 * @throws IOException
	 */
	@GetMapping("/resolve")
	public boolean resolve() throws IOException{
		BlockChain blockChain = BlockChain.getInstance();
		return blockChain.resolveConflicts();
	}

	/**
	 * 告诉服务器去挖掘新的区块：
	 * {
		    "index": 2,
		    "proof": 35293,
		    "previous_hash": "3c830051c22d330c392515654364c9412af90dda8e4cf79f97a766df56d9f1fd",
		    "timestamp": 1521700232360,
		    "transactions": [
		        {
		            "amount": 5, --存储的新交易信息
		            "sender": "8358778310cd44de843d3169c4b753f5",
		            "recipient": "109829453dajid0cd44de843d3169c4b87hjh"
		        },
		        {
		            "amount": 1, --挖矿者的奖励
		            "sender": "0",
		            "recipient": "710945dd78fa446687f3a9b14ab50e12"
		        }
		    ]
		}
	 */
	@GetMapping("/mine")
	public Block mine(){
		BlockChain blockChain = BlockChain.getInstance();
		Block lastBlock = blockChain.lastBlock();
        long lastProof = Long.parseLong(lastBlock.getProof() + "");
        long proof = ProofWork.proofOfWork(lastProof);

        // 给工作量证明的节点提供奖励，发送者为 "0" 表明是新挖出的币
        String uuid = (String) servletContext.getAttribute("uuid");
        blockChain.newTransactions("0", uuid, 1);

        // 构建新的区块
        Block newBlock = blockChain.newBlock(proof, null);

        // 返回新区块的数据给客户端
        return newBlock;
	}

	/**
	 * 用于输出整个区块链的数据
	 */
	@GetMapping("/chain")
	public Map<String, Object> chain(){
		BlockChain blockChain = BlockChain.getInstance();
        Map<String, Object> response = new HashMap<String, Object>();
        response.put("chain", blockChain.getChain());
        response.put("length", blockChain.getChain().size());
        return response;
	}

	/**
	 * 用于接收并处理新的交易信息：创建一个交易并添加到区块
	 * {
		 "sender": "8358778310cd44de843d3169c4b753f5",
		 "recipient": "109829453dajid0cd44de843d3169c4b87hjh",
		 "amount": 5
		}
	 */
	@PostMapping("/transactions/new")
	public String transactions(@RequestBody TransactionRecord record){
        // 新建交易信息
        BlockChain blockChain = BlockChain.getInstance();
        int index = blockChain.newTransactions(record.getSender(), record.getRecipient(), record.getAmount());

        return "Transaction will be added to Block " + index;
	}

}
